package com.qianfeng.chinatelcom.apiinterface.service.impl;


//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼            BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  


import com.qianfeng.chinatelcom.apiinterface.feign.CacheService;
import com.qianfeng.chinatelcom.apiinterface.pojo.MessageBody;
import com.qianfeng.chinatelcom.apiinterface.service.CheckSmsService;
import com.qianfeng.chinatelcom.apiinterface.service.SmsMQService;
import com.qianfeng.chinatelcom.apiinterface.utils.PhoneFormatCheckUtil;
import com.qianfeng.smsplatform.common.constants.CacheConstants;
import com.qianfeng.smsplatform.common.constants.InterfaceExceptionDict;
import com.qianfeng.smsplatform.common.exceptions.MyBaseException;
import com.qianfeng.smsplatform.common.model.Standard_Submit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by jackiechan on 2021/11/25 16:51
 *
 * @author jackiechan
 * @version 1.0
 * //TODO 给最美丽的芳姐介绍学生
 * @since 1.0
 */
@Service
public class CheckSmsServiceImpl  implements CheckSmsService {

    private SmsMQService smsMQService;

    @Autowired
    public void setSmsMQService(SmsMQService smsMQService) {
        this.smsMQService = smsMQService;
    }

    private CacheService cacheService;

    @Autowired
    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    @Override
    public List<String> checkSms(MessageBody body, String ip) {
        //检查内容是否和手机号的数量匹配
        String[] contents = body.getContents();
        if (contents == null || contents.length == 0) {
            //没有传递短信内容 怎么办
            System.err.println("没有传递短信内容");
            throw new MyBaseException("没有传递短信内容", InterfaceExceptionDict.RETURN_STATUS_MESSAGE_ERROR);
        }

        //检查手机号
        String mobiles = body.getMobiles();//获取到手机号,手机号可能会有多个
        if (ObjectUtils.isEmpty(mobiles)) {
            throw new MyBaseException("没有传递手机号", InterfaceExceptionDict.RETURN_STATUS_MOBILE_ERROR);
        }
        String[] mobileArray = mobiles.split(",");//将手机号转成数组
        if (contents.length != 1 && contents.length != mobileArray.length) {
            //内容的数量和手机号的数量不匹配
            throw new MyBaseException("内容的数量和手机号的数量不匹配", InterfaceExceptionDict.RETURN_STATUS_MESSAGE_PHONE_NOT_MATCH);

        }


        //检查手机号是不是合法的手机号
        List<String> okList = new ArrayList<>(); //保存合法手机号的
        List<String> failList = new ArrayList<>();//保存不合法手机号的
        List<String> messageList = new ArrayList<>();//保存的是每个手机号对应的内容
//        for (String mobile : mobileArray) {
//            boolean isMobile = PhoneFormatCheckUtil.isChinaPhoneLegal(mobile);
//            //如果不是
//            if (isMobile) {
//                okList.add(mobile);
//            }else{
//                failList.add(mobile);//不是合法手机号
//            }
//
//        }
        int length = contents.length;//短信内容的长度
        for (int i = 0; i < mobileArray.length; i++) {
            String mobile = mobileArray[i];
            boolean isMobile = PhoneFormatCheckUtil.isChinaPhoneLegal(mobile);
//            //如果不是
            if (isMobile) {
                okList.add(mobile);
                //如果上面有非法的手机号,并且我们的短信内容是和它长度一一匹配的,我们就需要删除对应的信息内容
                //但是我们不知道出现问题的手机号的下标,并且知道了也无法从集合中删除,因为删除的时候会挪动数据,如果再删除会出现删除下标错误,比如期望删除 1 3 但是实际上会删除 1 4
                if (length == 1) {
                    messageList.add(contents[0]);
                } else {
                    messageList.add(contents[i]);//将对应位置的 ok 内容保存出来
                }
            } else {
                failList.add(mobile);//不是合法手机号
            }
        }

        System.err.println(failList);

        //检查用户名和密码
        //检查的时候我们要求传递的是 id,我们的用户的数据是通过
        Map userInfoMap = cacheService.hmget(CacheConstants.CACHE_PREFIX_CLIENT + body.getUsercode());
        if (userInfoMap == null||userInfoMap.size()==0) {
            //用户不存在,直接返回即可
            throw new MyBaseException("用户名或密码错误", InterfaceExceptionDict.RETURN_STATUS_CLIENTID_PWD_ERROR);
        }
        //怎么校验用户名和密码?密码是什么?密码并不是明文,但是用户传递过来的是明文
        //我们需要把用户的密码获取到,然后将传递的密码转成密文,然后再进行比较, 比如可以使用 MD5  SHA等方式
        //熵增,信息差  100G  薛定谔的猫,麦克斯韦妖 香农理论
        //DES,AES 对称加密, 加密和解密密码一样
        //RSA DSA //非对称加密, 加密和解密密码不一样  公钥,私钥--> ssh 证书, 大素数碰撞
        //按照用户名查询信息,查询到密码,我们可以把用户信息放入到缓存
        //以某个内容开头加上用户的标识, 用户的标识可以是 id 可以是用户名
        //用户信息会有很多,所以我们存放的是存 hash
        String pwd = (String) userInfoMap.get("pwd");//用户的密码
        String password = body.getPassword();//传递的密码
        //对传递的密码按照我们密码的规则进行处理
        String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if (!passwordMd5.equalsIgnoreCase(pwd)) {
            //密码错误
            throw new MyBaseException("用户名或密码错误", InterfaceExceptionDict.RETURN_STATUS_CLIENTID_PWD_ERROR);

        }
        //检查是不是在白名单内
        //获取到允许的 ip 列表
        String ipaddress = (String) userInfoMap.get("ipaddress");
        //判断当前的 ip 在不在列表中

        if (!ipaddress.contains(ip)) {
            //不在白名单中
            throw new MyBaseException("ip 不在白名单", InterfaceExceptionDict.RETURN_STATUS_IP_ERROR);

        }

        //一切都没有问题
        List<Standard_Submit> standard_submits = new ArrayList<>();
        //发送出去,通过 mq 发送出去
        for (int i = 0; i < okList.size(); i++) {
            String num = okList.get(i);//获取到每一个手机号
            String msg = messageList.get(i);//发送的内容
            Standard_Submit submit = new Standard_Submit();
            submit.setClientID(body.getUsercode());
            submit.setDestMobile(num);
            submit.setMessageContent(msg);
            submit.setSendTime(new Date());
            submit.setSrcSequenceId(body.getSrcSequenceId());
            standard_submits.add(submit);
        }

        smsMQService.sendSms2Mq(standard_submits);

        return failList;
    }
}
